#include "semaphore.h"
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define SEM_NUM           2

static int sem_id = -1;

static void print_err(char *str) {
    perror(str);
    exit(-1);
}

void signal_fun(int signo) {
    if (signo == SIGINT || signo == SIGTERM) {
        if (sem_id >= 0)
            sem_destroy(sem_id);
    }
}

/**
 * 示例:父进程和子进程同时通过终端打印,子进程打印完毕后父进程打印,父进程打印完毕后子进程打印,如此循环往复,周期为1s
 */
int main () {
    static int counter = 0;

    int ret;
    int semid = sem_get(SEM_NUM); // 创建或获取指定数量的信号量集
    int semnums[1] = {0}; // 存放信号量编号
    sem_id = semid;

    // 初始化信号量集合
    for (int i = 0; i < SEM_NUM; ++i) {
        if (i == 0) sem_init(semid, i, 1);
        else sem_init(semid, i, 0);
    }

    // 创建子线程
    ret = fork();
    if (ret < 0) print_err("fork fail");
    else if (ret == 0) { // 子进程
        printf("child pid = %d\n", getpid());

        char *str1 = "hello";
        char *str2 = "world";
        while (1) {
            semnums[0] = 0;
            sem_p(semid, semnums, 1); //  p sem 0

            printf("%d %s\n", counter++, str1);
            printf("%s\n", str2);

            semnums[0] = 1;
            sem_v(semid, semnums, 1); // v sem 1

            sleep(1);
        }
    }
    else { // 父进程
        printf("parent pid = %d\n", getpid());
        signal(SIGINT, signal_fun);
        signal(SIGTERM, signal_fun);

        char *str1 = "aaaaaa";
        char *str2 = "bbbbbbbb";
        while (1) {
            semnums[0] = 1;
            sem_p(semid, semnums, 1); // p sem 1

            printf("%d %s\n", counter++, str1);
            printf("%s\n", str2);

            semnums[0] = 0;
            sem_v(semid, semnums, 1); // v sem 0

            sleep(1);
        }
    }


    return 0;
}
